package net.ssta.core.db;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Map;

import net.ssta.core.util.format.ValueObjectFormat;

public class OracleDataBaseExecutor extends DataBaseExecutor
{
	protected OracleDataBaseExecutor(Connection conn){ super(conn); }
	
	protected Record fillRecord(ResultSet rs, ResultSetMetaData rsmd, Map<String, String> entryColumnType) throws SQLException 
	{
		Record record = new Record();
//		record.setColumnType(entryColumnType);
		int columnCount = rsmd.getColumnCount();
		for (int i = 1; i <= columnCount; i++)
		{
			Object object = null;
			String columnName = rsmd.getColumnName(i);
			switch(rsmd.getColumnType(i))
			{
				//DATE
				case 91		:object = rs.getTimestamp(columnName);break;
				default		:object = rs.getObject(columnName);
							 break;
			}
			record.addData(columnName, object);
		}
		return record;
	}

	protected void setPreparedStatementParameter(PreparedStatement pstmt, int paramIndex, int columnTypeCode, Object paramValue, ValueObjectFormat formatter) throws SQLException
	{
		switch(columnTypeCode)
		{
			//CHAR
			case 1:		pstmt.setString(paramIndex, (String)paramValue);
						break;
			//NUMBER
			case 2:		pstmt.setObject(paramIndex, getBigDecimalObject(paramValue,formatter));
						break;
			//VARCHAR2
			case 12:	pstmt.setString(paramIndex, (String)paramValue);
						break;
			//DATE
			case 91:	//do nothing, the same as TIMESTAMP
			//TIMESTAMP
			case 93:	Timestamp ts = getTimestampObject(paramValue, formatter);
						pstmt.setTimestamp(paramIndex, ts);
						break;
			//BLOB
			case 2004:	byte[] data = formatter.getBytes(paramValue);
						InputStream is = new ByteArrayInputStream(data);
						pstmt.setBinaryStream(paramIndex, is, data.length);
						break;
			//CLOB
			case 2005:	String s = formatter.getString(paramValue, "");
						Reader reader = new StringReader(s);
						pstmt.setCharacterStream(paramIndex, reader, ((String)paramValue).length());
						break;
			default:    throw new RuntimeException("one oracle column type in used is not supported! you can use the following type : CHAR/NUMBER/VARCHAR2/DATE/TIMESTAMP/BLOB/CLOB.");
		}
	}

	private Object getBigDecimalObject(Object value, ValueObjectFormat formatter)
	{
		Object retObject = value;
		if (value != null && (value instanceof String) && !"".equals(value)) 
		{
			retObject = new BigDecimal((String)value);
		}
		return retObject;
	}

	private Timestamp getTimestampObject(Object value, ValueObjectFormat formatter)
	{
		java.util.Date javaUtilDate = formatter.getJavaUtilDate(value, null);
		return value == null ? null : new Timestamp(javaUtilDate.getTime());
	}
}

